package com.charm.restaurant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.charm.restaurant.common.Result;
import com.charm.restaurant.entity.Points;
import com.charm.restaurant.entity.PointsRecord;
import com.charm.restaurant.mapper.PointsMapper;
import com.charm.restaurant.mapper.PointsRecordMapper;
import com.charm.restaurant.service.PointsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 积分服务实现类
 */
@Slf4j
@Service
public class PointsServiceImpl extends ServiceImpl<PointsMapper, Points> implements PointsService {

    @Autowired
    private PointsRecordMapper pointsRecordMapper;

    /**
     * 获取用户积分信息
     */
    @Override
    public Result<Points> getUserPoints() {
        // 模拟获取当前登录用户ID
        Long userId = 1L;

        // 查询用户积分信息
        LambdaQueryWrapper<Points> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Points::getUserId, userId);
        Points points = this.getOne(queryWrapper);

        // 如果用户没有积分记录，创建一个新的
        if (points == null) {
            points = new Points();
            points.setUserId(userId);
            points.setTotal(0);
            points.setLevel(1);
            points.setRemark("新用户初始积分");
            this.save(points);
        }

        return Result.success(points);
    }

    /**
     * 获取用户积分记录
     */
    @Override
    public Result<Page<PointsRecord>> getPointsRecords(int page, int pageSize) {
        // 模拟获取当前登录用户ID
        Long userId = 1L;

        // 分页查询用户积分记录
        Page<PointsRecord> pageInfo = new Page<>(page, pageSize);
        LambdaQueryWrapper<PointsRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PointsRecord::getUserId, userId);
        queryWrapper.orderByDesc(PointsRecord::getCreateTime);
        Page<PointsRecord> recordPage = pointsRecordMapper.selectPage(pageInfo, queryWrapper);

        return Result.success(recordPage);
    }

    /**
     * 增加积分
     */
    @Override
    @Transactional
    public Result<String> addPoints(Integer points, Integer type, Long orderId, String remark) {
        if (points <= 0) {
            return Result.error("积分必须大于0");
        }

        // 模拟获取当前登录用户ID
        Long userId = 1L;

        // 查询用户积分信息
        LambdaQueryWrapper<Points> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Points::getUserId, userId);
        Points userPoints = this.getOne(queryWrapper);

        // 如果用户没有积分记录，创建一个新的
        if (userPoints == null) {
            userPoints = new Points();
            userPoints.setUserId(userId);
            userPoints.setTotal(0);
            userPoints.setLevel(1);
            userPoints.setRemark("新用户初始积分");
            this.save(userPoints);
        }

        // 记录变动前的积分
        Integer beforePoints = userPoints.getTotal();

        // 增加积分
        userPoints.setTotal(beforePoints + points);

        // 更新积分等级
        updatePointsLevel(userPoints);

        // 更新用户积分信息
        this.updateById(userPoints);

        // 创建积分记录
        PointsRecord record = new PointsRecord();
        record.setUserId(userId);
        record.setPoints(points);
        record.setType(type);
        record.setOrderId(orderId);
        record.setBeforePoints(beforePoints);
        record.setAfterPoints(userPoints.getTotal());
        record.setRemark(remark);
        pointsRecordMapper.insert(record);

        return Result.success("积分增加成功");
    }

    /**
     * 使用积分
     */
    @Override
    @Transactional
    public Result<String> usePoints(Integer points, Long orderId, String remark) {
        if (points <= 0) {
            return Result.error("使用积分必须大于0");
        }

        // 模拟获取当前登录用户ID
        Long userId = 1L;

        // 查询用户积分信息
        LambdaQueryWrapper<Points> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Points::getUserId, userId);
        Points userPoints = this.getOne(queryWrapper);

        // 检查用户是否有足够的积分
        if (userPoints == null || userPoints.getTotal() < points) {
            return Result.error("积分不足");
        }

        // 记录变动前的积分
        Integer beforePoints = userPoints.getTotal();

        // 减少积分
        userPoints.setTotal(beforePoints - points);

        // 更新积分等级
        updatePointsLevel(userPoints);

        // 更新用户积分信息
        this.updateById(userPoints);

        // 创建积分记录
        PointsRecord record = new PointsRecord();
        record.setUserId(userId);
        record.setPoints(-points); // 使用积分为负数
        record.setType(4); // 4:消费使用
        record.setOrderId(orderId);
        record.setBeforePoints(beforePoints);
        record.setAfterPoints(userPoints.getTotal());
        record.setRemark(remark);
        pointsRecordMapper.insert(record);

        return Result.success("积分使用成功");
    }

    /**
     * 签到获取积分
     */
    @Override
    @Transactional
    public Result<String> signIn() {
        // 模拟获取当前登录用户ID
        Long userId = 1L;

        // 检查今天是否已经签到
        LambdaQueryWrapper<PointsRecord> recordQueryWrapper = new LambdaQueryWrapper<>();
        recordQueryWrapper.eq(PointsRecord::getUserId, userId);
        recordQueryWrapper.eq(PointsRecord::getType, 2); // 2:签到获得
        recordQueryWrapper.ge(PointsRecord::getCreateTime, LocalDate.now().atStartOfDay());
        recordQueryWrapper.le(PointsRecord::getCreateTime, LocalDateTime.now());
        Long count = pointsRecordMapper.selectCount(recordQueryWrapper);

        if (count > 0) {
            return Result.error("今天已经签到过了");
        }

        // 签到获得5积分
        return addPoints(5, 2, null, "每日签到");
    }

    /**
     * 获取积分统计信息
     */
    @Override
    public Result<Map<String, Object>> getPointsStatistics() {
        // 模拟获取当前登录用户ID
        Long userId = 1L;

        // 查询用户积分信息
        LambdaQueryWrapper<Points> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Points::getUserId, userId);
        Points userPoints = this.getOne(queryWrapper);

        // 如果用户没有积分记录，创建一个新的
        if (userPoints == null) {
            userPoints = new Points();
            userPoints.setUserId(userId);
            userPoints.setTotal(0);
            userPoints.setLevel(1);
            userPoints.setRemark("新用户初始积分");
            this.save(userPoints);
        }

        // 计算下一等级所需积分
        int nextLevelPoints = getNextLevelPoints(userPoints.getLevel(), userPoints.getTotal());

        // 计算等级进度
        double progress = 0;
        if (userPoints.getLevel() < 5) {
            int currentLevelMinPoints = getLevelMinPoints(userPoints.getLevel());
            int nextLevelMinPoints = getLevelMinPoints(userPoints.getLevel() + 1);
            progress = (double) (userPoints.getTotal() - currentLevelMinPoints) / (nextLevelMinPoints - currentLevelMinPoints) * 100;
        } else {
            progress = 100;
        }

        // 统计信息
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("total", userPoints.getTotal());
        statistics.put("level", userPoints.getLevel());
        statistics.put("levelName", getLevelName(userPoints.getLevel()));
        statistics.put("nextLevelPoints", nextLevelPoints);
        statistics.put("progress", progress);

        return Result.success(statistics);
    }

    /**
     * 更新积分等级
     */
    private void updatePointsLevel(Points points) {
        int total = points.getTotal();
        if (total < 100) {
            points.setLevel(1);
        } else if (total < 500) {
            points.setLevel(2);
        } else if (total < 1000) {
            points.setLevel(3);
        } else if (total < 2000) {
            points.setLevel(4);
        } else {
            points.setLevel(5);
        }
    }

    /**
     * 获取等级名称
     */
    private String getLevelName(int level) {
        switch (level) {
            case 1:
                return "普通会员";
            case 2:
                return "银卡会员";
            case 3:
                return "金卡会员";
            case 4:
                return "白金会员";
            case 5:
                return "钻石会员";
            default:
                return "未知等级";
        }
    }

    /**
     * 获取等级最低积分
     */
    private int getLevelMinPoints(int level) {
        switch (level) {
            case 1:
                return 0;
            case 2:
                return 100;
            case 3:
                return 500;
            case 4:
                return 1000;
            case 5:
                return 2000;
            default:
                return 0;
        }
    }

    /**
     * 获取下一等级所需积分
     */
    private int getNextLevelPoints(int currentLevel, int currentPoints) {
        if (currentLevel >= 5) {
            return 0; // 已经是最高等级
        }

        int nextLevelMinPoints = getLevelMinPoints(currentLevel + 1);
        return nextLevelMinPoints - currentPoints;
    }
}
